package com.hitqz.robot.biz.controller;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.collect.Lists;
import com.hitqz.robot.api.business.entity.PatrolResultEntity;
import com.hitqz.robot.api.business.enums.FormConfigEnum;
import com.hitqz.robot.api.business.enums.TicketsStatusEnum;
import com.hitqz.robot.api.business.model.param.tickets.AddOrUpdateTicketsParams;
import com.hitqz.robot.api.business.model.param.tickets.QueryTasksTicketsParams;
import com.hitqz.robot.api.business.model.param.tickets.QueryTicketsParams;
import com.hitqz.robot.api.business.model.vo.form.FormConfigModalVo;
import com.hitqz.robot.api.business.model.vo.form.FormConfigNameOptionVo;
import com.hitqz.robot.api.business.model.vo.form.FormFieldConfigModalVo;
import com.hitqz.robot.api.business.model.vo.tickets.TicketsTaskVo;
import com.hitqz.robot.api.business.model.vo.tickets.TicketsVo;
import com.hitqz.robot.api.common.entity.Robot;
import com.hitqz.robot.api.common.entity.Tickets;
import com.hitqz.robot.api.common.entity.TicketsTask;
import com.hitqz.robot.biz.service.*;
import com.hitqz.robot.common.core.util.R;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeoutException;

/**
 * @author xupkun
 * @date 2024/6/13
 */

@RestController
@AllArgsConstructor
@RequestMapping("/tickets")
@Tag(name = "工单管理")
@Slf4j
public class TicketsController {

    private final TicketsService ticketsService;

    private final TicketsTaskService ticketsTaskService;

    private final FormConfigService formConfigService;

    private final FormFieldConfigService formFieldConfigService;

    private final RobotService robotService;

    private final PatrolResultService patrolResultService;

    @GetMapping(value = "/execute/{ticketsId}")
    @Operation(summary = "启动工单")
    public R executeTask(@PathVariable Integer ticketsId) throws ExecutionException, InterruptedException, TimeoutException {
        try {
            return ticketsService.executeFlowChain(ticketsId);
        }catch (Exception e){
            return R.failed("执行任务失败");
        }
    }

    @GetMapping(value = "{ticketsId}")
    @Operation(summary = "根据id获取工单编辑对话框")
    public R<AddOrUpdateTicketsParams> ticketsEditModal(@PathVariable Integer ticketsId) {
        Tickets tickets = ticketsService.getById(ticketsId);
        AddOrUpdateTicketsParams params = new AddOrUpdateTicketsParams();
        params.setId(tickets.getId());
        params.setName(tickets.getName());
        params.setFormName(tickets.getFormName());
        String content = tickets.getContent();
        params.setContent(content);
        if (StrUtil.isNotBlank(tickets.getFormName())){
            FormConfigModalVo formConfigModalVo = formConfigService.getFormModal(tickets.getFormName());
            params.setForm(formConfigModalVo);
            if (StrUtil.isNotBlank(content)) {
                for (FormFieldConfigModalVo field : CollUtil.emptyIfNull(formConfigModalVo.getFields())) {
                    JSONObject values = JSONObject.parseObject(content);
                    String name = field.getName();
                    if (values.containsKey(name)) {
                        field.setCurrentValue(values.getString(name));
                    }
                }
            }
        }
        return R.ok(params);
    }


    @PostMapping("/page")
    @Operation(summary = "分页查询工单列表")
    public R<Page<TicketsVo>> page(@RequestBody QueryTicketsParams queryTicketsParams) {
        Page page = new Page<>(queryTicketsParams.getCurrent(),queryTicketsParams.getSize());
        Page<Tickets> data = ticketsService.page( page,
                Wrappers.<Tickets>lambdaQuery()
                        .like(StrUtil.isNotBlank(queryTicketsParams.getName()), Tickets::getName,
                                queryTicketsParams.getName()).or().like(StrUtil.isNotBlank(queryTicketsParams.getName()),
                                Tickets::getName,
                                queryTicketsParams.getName()).orderByDesc(Tickets::getCreateTime));
        Page<TicketsVo> voPage = new Page<>();
        BeanUtil.copyProperties(data, voPage, false);
        List<TicketsVo> vos = Lists.newArrayList();
        
        for (Tickets ticket: data.getRecords()) {
            TicketsVo vo = new TicketsVo();
            BeanUtil.copyProperties(ticket, vo, false);
            vos.add(vo);
        }
        voPage.setRecords(vos);
        return R.ok(voPage);
    }


    @PostMapping(value = "pageTasks")
    @Operation(summary = "查询工单任务")
    public R<Page<TicketsTaskVo>> pageTasks(@RequestBody QueryTasksTicketsParams params) {
        Page page = new Page<>(params.getCurrent(), params.getSize());
        Page<TicketsTask> data = ticketsTaskService.page( page,
                Wrappers.<TicketsTask>lambdaQuery()
                        .eq(TicketsTask::getTicketsId, params.getTicketsId())
                        .like(StrUtil.isNotBlank(params.getContent()), TicketsTask::getContent,
                                params.getContent()).or().like(StrUtil.isNotBlank(params.getContent()),
                                TicketsTask::getContent, params.getContent()));

        List<TicketsTaskVo> vos = Lists.newArrayList();
        for (TicketsTask task : data.getRecords()) {
            TicketsTaskVo vo = new TicketsTaskVo();
            BeanUtil.copyProperties(task, vo, false);
            vos.add(vo);
        }
        Page<TicketsTaskVo> taskVoPage = new Page<>();
        BeanUtil.copyProperties(data, taskVoPage);
        taskVoPage.setRecords(vos);
        return R.ok(taskVoPage);
    }


    @GetMapping("/form/title")
    @Operation(summary = "获取工单动态表单选项")
    public R<List<FormConfigNameOptionVo>> titleOption() {
        Robot robot = robotService.getDefaultRobot();
        ArrayList<FormConfigNameOptionVo> list = new ArrayList<>();
        for (FormConfigEnum formConfigEnum : FormConfigEnum.values()) {
            if (formConfigEnum.getFormName().contains("tickets_params")
             && formConfigEnum.getFormName().contains(robot.getRobotModel().toLowerCase())) {
                FormConfigNameOptionVo dto = new FormConfigNameOptionVo();
                dto.setFormName(formConfigEnum.getFormName());
                dto.setFormTitle(formConfigEnum.getFormTitle());
                list.add(dto);
                formConfigService.syncFormMoal(formConfigEnum.getFormName());
            }
        }
        return R.ok(list);
    }

    @GetMapping("/modal/{formName}")
    @Operation(summary = "获取工单动态表单")
    public R<FormConfigModalVo> form(@PathVariable(value = "formName")String formName) {
        FormConfigModalVo formModal = formConfigService.getFormModal(formName);
        if (formModal == null){
            return R.failed("表单不存在");
        }
        return R.ok(formModal);
    }


    @PostMapping("/modal/submit")
    @Operation(summary = "新增/修改工单")
    public R<Tickets> submit(@RequestBody AddOrUpdateTicketsParams dto){
        log.info("提交表单参数:{}", dto);
        dto.setContent(JSONObject.toJSONString(dto.getForm()));
        Tickets tickets = new Tickets();
        //解析表单到规则
        tickets.setContent(dto.getContent());
        tickets.setName(dto.getName());
        FormConfigModalVo form= dto.getForm();
        if (form!=null){
            tickets.setFormName(form.getFormName());
            JSONObject result = new JSONObject();
            List<FormFieldConfigModalVo> fields = form.getFields();
            for (FormFieldConfigModalVo field : fields) {
                String name = field.getName();
                String currentValue = field.getCurrentValue();
                result.put(name, currentValue);
            }
            //tickets.setContent(result.toJSONString());
        }
        if (dto.getId()==null || dto.getId()==0) {
            Robot defaultRobot = robotService.getDefaultRobot();
            tickets.setCreateTime(new Date());
            tickets.setStatus(0);
            tickets.setAllotStatus(TicketsStatusEnum.ALLOT_ALLOCATION.getCode());
            tickets.setAllotRobotSn(defaultRobot.getRobotSn());
            tickets.setAllotRobotName(defaultRobot.getRobotName());
            ticketsService.save(tickets);
            log.info("tickets id:{}",tickets.getId());
        }else {
            tickets.setId(dto.getId());
            tickets.setUpdateTime(new Date());
            Tickets oldTickets = ticketsService.getById(dto.getId());
            if (!Objects.equals(oldTickets.getContent(),tickets.getContent())){
                //旧的task和 result
                ticketsTaskService.remove(Wrappers.<TicketsTask>lambdaQuery().eq(TicketsTask::getTicketsId,tickets.getId()));
                patrolResultService.remove(Wrappers.<PatrolResultEntity>lambdaQuery().eq(PatrolResultEntity::getTicketsId,tickets.getId()));
            }
            ticketsService.updateById(tickets);
        }
        //tickets.setServerId(0); 在服务器那边的工单id，用于同步
        ticketsService.addTask(tickets);
        return R.ok(tickets);
    }


    @Operation(description = "删除工单", summary = "删除工单")
    @DeleteMapping
    public R removeById(@RequestBody Long[] ids) {
        return R.ok(ticketsService.removeById(ids));
    }





    @GetMapping("/fast/modal/data")
    @Operation(summary = "获取工单任务的类型数据")
    public R<FormConfigModalVo> modalData() {
        Robot robot = robotService.getDefaultRobot();
        ArrayList<FormConfigNameOptionVo> list = new ArrayList<>();
        for (FormConfigEnum formConfigEnum : FormConfigEnum.values()) {
            if (formConfigEnum.getFormName().contains("tickets_params")
                    && formConfigEnum.getFormName().contains(robot.getRobotModel().toLowerCase())) {
                FormConfigNameOptionVo dto = new FormConfigNameOptionVo();
                dto.setFormName(formConfigEnum.getFormName());
                dto.setFormTitle(formConfigEnum.getFormTitle());
                list.add(dto);
            }
        }
        if (CollUtil.isNotEmpty(list)) {
            FormConfigModalVo formModal = formConfigService.getFormModal(list.get(0).getFormName());
            if (formModal == null){
                return R.failed("表单不存在");
            }
            return R.ok(formModal);
        }
       return R.failed("未找到任务配置数据");
    }


    @PostMapping("/fast/modal/submit")
    @Operation(summary = "全局快速创建任务,启动任务")
    public R<Tickets> fastsubmit(@RequestBody AddOrUpdateTicketsParams dto){
        log.info("快速提交任务:{}", dto);
        dto.setName("快速创建任务:" + DateUtil.format(new Date(), "yyyy-MM-dd-HH-mm-ss"));
        dto.setContent(JSONObject.toJSONString(dto.getForm()));
        Tickets tickets = new Tickets();
        //解析表单到规则
        tickets.setContent(dto.getContent());
        tickets.setName(dto.getName());
        FormConfigModalVo form= dto.getForm();
        if (form!=null){
            tickets.setFormName(form.getFormName());
            JSONObject result = new JSONObject();
            List<FormFieldConfigModalVo> fields = form.getFields();
            for (FormFieldConfigModalVo field : fields) {
                String name = field.getName();
                String currentValue = field.getCurrentValue();
                result.put(name, currentValue);
            }
        }
        if (dto.getId()==null || dto.getId()==0) {
            Robot defaultRobot = robotService.getDefaultRobot();
            tickets.setCreateTime(new Date());
            tickets.setStatus(0);
            tickets.setAllotStatus(TicketsStatusEnum.ALLOT_ALLOCATION.getCode());
            tickets.setAllotRobotSn(defaultRobot.getRobotSn());
            tickets.setAllotRobotName(defaultRobot.getRobotName());
            ticketsService.save(tickets);
            log.info("tickets id:{}",tickets.getId());
        }else {
            tickets.setId(dto.getId());
            tickets.setUpdateTime(new Date());
            Tickets oldTickets = ticketsService.getById(dto.getId());
            if (!Objects.equals(oldTickets.getContent(),tickets.getContent())){
                //旧的task和 result
                ticketsTaskService.remove(Wrappers.<TicketsTask>lambdaQuery().eq(TicketsTask::getTicketsId,tickets.getId()));
                patrolResultService.remove(Wrappers.<PatrolResultEntity>lambdaQuery().eq(PatrolResultEntity::getTicketsId,tickets.getId()));
            }
            ticketsService.updateById(tickets);
        }
        ticketsService.addTask(tickets);
        log.info("[tickets]id:{} execute finish", tickets.getId());
        try {
            ticketsService.executeFlowChain(tickets.getId().intValue());
        } catch (Exception e) {
            ticketsService.removeById(tickets.getId());
            return R.failed("创建启动任务失败");
        }
        return R.ok(tickets);
    }





}
